<template>
    <view class="xilu flex-box flex-align-start">
        <scroll-view class="xilu_left bg-white" :scroll-top="scrollTop" :scroll-into-view="itemId">
            <view v-for="(item,index) in categoryList" class="item u-tab-item flex-box flex-center" :id="item.id"
                :class="leftIndex == index?'active fwb':''" @click="swichMenu(index)">{{item.name}}</view>
        </scroll-view>
        <view class="xilu_right flex-grow-1">
            <image v-if="bannerList.length>0" :src="bannerList[0].thumb_image" mode="aspectFill" class="xilu_adv"></image>
            <scroll-view class="xilu_right_scroll" :scroll-top="scrollRightTop" scroll-y scroll-with-animation @scroll="rightScroll">
                <view v-for="(item,index) in categoryList" :id="item.id" class="right_box">
                    <view class="fs30 col10 pb30">{{item.name}}</view>
                    <view class="xilu_goods_box bg-white flex-box flex-wrap mb30">
                        <view v-for="(items,indexs) in item.childlist" :key="indexs" class="xilu_goods_item" @click="productList(items.id)">
                            <view class="pic_box">
                                <image :src="items.thumb_image_text" mode="aspectFill"></image>
                            </view>
                            <view class="fs24 col5 tc m-ellipsis mt20">{{items.name}}</view>
                        </view>
                    </view>
                </view>
            </scroll-view>
        </view>
    </view>
</template>

<script>
    export default {
        data() {
            return {
                leftIndex: 0,
                arr: [], // 储存距离顶部高度的数组
                scrollTop: 0, //tab标题的滚动条位置
                oldScrollTop: 0, // tab标题的滚动条旧位置
                menuHeight: 0, // 左边菜单的高度
                menuItemHeight: 0, // 左边菜单item的高度
                scrollRightTop:0,
				bannerList:[],
                categoryList: [],
            };
        },
        onReady() {
            this.getMenuItemTop();
        },
		onLoad() {
			//1.轮播
			this.fetchBanner();
			//2分类
			this.fetchCategoryList();
		},
        methods: {
			fetchBanner(){
				this.$core.get({url:'xilumarket.banner/banners',data:{group:'category_index'},loading:false,success:ret=>{
					this.bannerList = ret.data;
				}})
			},
			fetchCategoryList(){
				this.$core.get({url:'xilumarket.product_category/lists',data:{},loading:false,success:ret=>{
					this.categoryList = ret.data;
				}})
			},
			productList(id){
				uni.navigateTo({
					url: '/pages/goods_list/goods_list?category_id='+id
				})
			},
            /**
             * 点击左边的栏目切换
             * @index 传入的 ID
             */
            async swichMenu(index) {
                if (this.arr.length == 0) {
                    await this.getMenuItemTop();
                }
                if (index == this.leftIndex) return;
                this.scrollRightTop = this.oldScrollTop;
                this.$nextTick(function() {
                    this.scrollRightTop = this.arr[index];
                    this.leftIndex = index;
                    this.leftMenuStatus(index);
                })
            },
            /**
             * 获取一个目标元素的高度
             * @elClass 元素的类名
             * @dataVal 储存高度的对象
             */
            getElRect(elClass, dataVal) {
                new Promise((resolve, reject) => {
                    const query = uni.createSelectorQuery().in(this);
                    query.select('.' + elClass).fields({
                        size: true
                    }, res => {
                        // 如果节点尚未生成，res值为null，循环调用执行
                        if (!res) {
                            setTimeout(() => {
                                this.getElRect(elClass);
                            }, 10);
                            return;
                        }
                        this[dataVal] = res.height;
                        resolve();
                    }).exec();
                })
            },
            /**
             * 获取右边菜单每个item到顶部的距离
             * 储存到 arr 数组里面用于后面滚动判断
             */
            getMenuItemTop() {
                new Promise(resolve => {
                    let selectorQuery = uni.createSelectorQuery();
                    selectorQuery.selectAll('.right_box').boundingClientRect((rects) => {
                        // 如果节点尚未生成，rects值为[](因为用selectAll，所以返回的是数组)，循环调用执行
                        if (!rects.length) {
                            setTimeout(() => {
                                this.getMenuItemTop();
                            }, 10);
                            return;
                        }
                        rects.forEach((rect) => {
                            // 视情况而定，这里减去rects[0].top，是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
                            this.arr.push(rect.top - rects[0].top);
                            // this.arr.push(rect.top);
                            console.log(this.arr)
                            resolve();
                        })
                    }).exec()
                })
            },
            /**
             * 右边菜单滚动
             * 如果不存在height2，意味着数据循环已经到了最后一个，设置左边菜单为最后一项即可
             */
            async rightScroll(e) {
                this.oldScrollTop = e.detail.scrollTop;
                if (this.arr.length == 0) {
                    await this.getMenuItemTop();
                }
                if (this.timer) return;
                if (!this.menuHeight) {
                    await this.getElRect('xilu_left', 'menuHeight');
                }
                setTimeout(() => { // 节流
                    this.timer = null;
                    // scrollHeight为右边菜单垂直中点位置
                    // let scrollHeight = e.detail.scrollTop + this.menuHeight / 2;
                    // scrollHeight为右边菜单头部位置
                    let scrollHeight = e.detail.scrollTop + 100;
                    for (let i = 0; i < this.arr.length; i++) {
                        let height1 = this.arr[i];
                        let height2 = this.arr[i + 1];
                        if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
                            this.leftMenuStatus(i);
                            return;
                        }
                    }
                }, 10)
            },
            /**
             * 观测元素相交状态
             * 检测右边scroll-view的id为itemxx的元素与right-box的相交状态
             * 如果跟.right-box底部相交，就动态设置左边栏目的活动状态
             */
            async observer() {
                this.goodsList.map((val, index) => {
                    let observer = uni.createIntersectionObserver(this);
                    observer.relativeTo('.right-box', {
                        top: 0
                    }).observe('#item' + index, res => {
                        if (res.intersectionRatio > 0) {
                            let id = res.id.substring(4);
                            this.leftMenuStatus(id);
                        }
                    })
                })
            },
            /**
             * 设置左边菜单的滚动状态
             * @index 传入的 ID
             */
            async leftMenuStatus(index) {
                this.leftIndex = index;
                // 如果为0，意味着尚未初始化
                if (this.menuHeight == 0 || this.menuItemHeight == 0) {
                    await this.getElRect('xilu_left', 'menuHeight');
                    await this.getElRect('u-tab-item', 'menuItemHeight');
                }
                // 将菜单活动item垂直居中
                this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
            }
        },
    }
</script>

<style lang="scss" scoped>
    .xilu {
        padding-top: 20rpx;
        background: #F7F9FD;

        &_adv {
            width: 510rpx;
            height: 140rpx;
            border-radius: 15rpx;
            display: block;
            margin-bottom: 30rpx;
        }

        &_left {
            height: calc(100vh - 20rpx);
            overflow-y: scroll;
            width: 200rpx;
            border-radius: 0rpx 15rpx 15rpx 0rpx;

            .item {
                height: 110rpx;

                &.active {
                    background: #F7F9FD;
                }
            }
        }

        &_right {
            padding: 0 20rpx;

            &_scroll {
                height: calc(100vh - 190rpx);

            }
        }

        &_goods_box {
            padding: 30rpx 30rpx 0;
            box-shadow: 0rpx 4rpx 20rpx 5rpx rgba(183, 189, 202, 0.05);
            border-radius: 15rpx;

            .pic_box {
                width: 130rpx;
                height: 130rpx;
                background: #F7F9FD;
                border-radius: 10rpx;

                image {
                    width: 130rpx;
                    height: 130rpx;
                }
            }
        }

        &_goods_item {
            width: 130rpx;
            margin-right: 30rpx;
            padding-bottom: 40rpx;

            &:nth-of-type(3n) {
                margin-right: 0;
            }
        }
    }
</style>
